home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok59.lha
/
AmokEd_V1.02b
/
txt
/
EdKeyboard.mod
< prev
next >
Wrap
Text File
|
1993-08-15
|
21KB
|
669 lines
(*************************************************************************
:Program. EdKeyboard.mod
:Contents. Keyboard-Routines for Amok-Editor
:Author. Hartmut Goebel
:Copyright. Copyright © 1987 by Matthew Dillon
:Copyright. Oberon implementation Copyright © 1990 by Hartmut Goebel
:Language. Oberon
:Translator. Amiga Oberon V2.00
:History. V0.1, 07 Nov 1990 Hartmut Goebel
:History. V1.0, 14 Apr 1991 Hartmut Goebel [hG]
:History. V1.1, 25 Apr 1991 [hG] -Bug NKx = KKx, Code optimiert
:History. V1.1, 25 Apr 1991 [hG] z.T. e.Alloc/FreeMem statt New/Disp.
:History. V1.1a 24 May 1991 [hG] -SpecKeyCode-Dummy (war Bug in V1.17.1)
:History. V1.1b 07 Aug 1991 [hG] -Bug in GetCodeQual (-str.Upper(key))
:Date. 30 Aug 1991 20:34:05
*************************************************************************)
MODULE EdKeyboard;
IMPORT
ASCII,
e : Exec,
con: Console,
edE: EdErrors,
edG: EdGlobalVars,
edL: EdLowLevel,
ie : InputEvent,
I : Intuition,
ol : OberonLib,
sl : SupLib,
str: Strings,
sys: SYSTEM;
CONST
qualShift = 1; qualCtrl = 2; qualAmiga = 3; qualAlt = 4;
qualLmb = 5; qualMmb = 6; qualRmb = 7;
Hashsize* = 64 (* was: KeyMap.maxKeys *);
NumRawKeyCodes = 128; (* lt. ARKM Libs & Devs max. mögl. Raw-Codes *)
NumDefaultKeys = 60;
SpecKeyNum = 43;
qMove* = 06BX;
ReturnRawCode = 44X;
Return = "return";
UnknownKey = "Unknown Key";
TYPE
SpecKeyCode = STRUCT
key: ARRAY 3 OF CHAR;
code: BYTE;
END;
SpecKeyCodeArray = ARRAY SpecKeyNum OF SpecKeyCode;
HashPtr* = POINTER TO Hash;
Hash* = STRUCT
next*: HashPtr;
code*: BYTE; (* Keycode *)
(*mask: SHORTSET; (* qual. mask für was?? *)*)
qual*: SHORTSET; (* qual. comp *)
len*: INTEGER; (* incl. 00C, --> len = 0 für SysMap *)
map*: edG.StringPtr; (* Command String *)
END;
DefMapArray = ARRAY NumDefaultKeys OF STRUCT
from, to: edG.StringPtr;
END;
CONST
SpecKeyDef = SpecKeyCodeArray(
"ESC", 0, "F1", 0, "F2", 0, (* 0-2 *)
"F3" , 0, "F4", 0, "F5", 0, (* 3-5 *)
"F6" , 0, "F7", 0, "F8", 0, (* 6-8 *)
"F9" , 0, "F10", 0, "DEL", 0, (* 9-11 *)
"BAC", 0, "BS", 0, "TAB", 0, (* 12-14 *)
"HEL", 0, "RET", 44X, "UP", 0, (* 15-17 *)
"DOW", 0, "RIG", 0, "LEF", 0, (* 18-20 *)
"ENT", 43X, "NK-", 0, "NK.", 0, (* 21-23 *)
"NK0", 0, (* 24 *)
"NK1", 0, "NK2", 0, "NK3", 0, (* 25-27 *)
"NK4", 0, "NK5", 0, "NK6", 0, (* 28-30 *)
"NK7", 0, "NK8", 0, "NK9", 0, (* 31-33 *)
"NK(", 0, "NK)", 0, "NK/", 0, (* 34-36 *)
"NK*", 0, "NK+", 0, (* 37-38 *)
"LMB", 068X, "MMB", 06AX, (* 39-40 *)
"RMB", 069X, "MMO", qMove); (* 41-42 *)
DefaultMap = DefMapArray(
sys.ADR("up"), sys.ADR("up"),
sys.ADR("c-esc"), sys.ADR("recall"),
sys.ADR("return"), sys.ADR("return"),
sys.ADR("enter"), sys.ADR("return"),
sys.ADR("esc"), sys.ADR("esc"),
sys.ADR("down"), sys.ADR("down"),
sys.ADR("right"), sys.ADR("right"),
sys.ADR("left"), sys.ADR("left"),
sys.ADR("bs"), sys.ADR("bs"),
sys.ADR("del"), sys.ADR("del"),
sys.ADR("tab"), sys.ADR("tab"),
sys.ADR("a-up"), sys.ADR("scrollup"),
sys.ADR("a-down"), sys.ADR("scrolldown"),
sys.ADR("a-r"), sys.ADR("nextr"),
sys.ADR("a-u"), sys.ADR("while cl (tlate -32 right)"),
sys.ADR("a-l"), sys.ADR("while cu (tlate +32 right)"),
sys.ADR("s-up"), sys.ADR("top"),
sys.ADR("s-down"), sys.ADR("bottom"),
sys.ADR("s-right"), sys.ADR("last"),
sys.ADR("s-left"), sys.ADR("first"),
sys.ADR("s-tab"), sys.ADR("backtab"),
sys.ADR("s-del"), sys.ADR("deline"),
sys.ADR("s- "), sys.ADR("( )"), (* shift space to space *)
sys.ADR("c-1"), sys.ADR("goto block"),
sys.ADR("c-c"), sys.ADR(""), (* break.. map to a nop *)
sys.ADR("c-l"), sys.ADR("wleft"),
sys.ADR("c-r"), sys.ADR("wright"),
sys.ADR("c-i"), sys.ADR("insertmode on"),
sys.ADR("c-o"), sys.ADR("insertmode off"),
sys.ADR("c-j"), sys.ADR("join"),
sys.ADR("c-s"), sys.ADR("split first down"),
sys.ADR("c-del"), sys.ADR("remeol"),
sys.ADR("c-n"), sys.ADR("next"),
sys.ADR("c-p"), sys.ADR("prev"),
sys.ADR("c-/"), sys.ADR("escimm (find )"),
(*sys.ADR("c-]"), sys.ADR("ref"),*)
(*sys.ADR("c-["), sys.ADR("ctags"),*)
sys.ADR("c-g"), sys.ADR("escimm (goto )"),
sys.ADR("c-up"), sys.ADR("pageup"),
sys.ADR("c-down"), sys.ADR("pagedown"),
sys.ADR("c-q"), sys.ADR("quit"),
sys.ADR("c-f"), sys.ADR("reformat"),
sys.ADR("c-w"), sys.ADR("toggle wordwrap"),
sys.ADR("f1"), sys.ADR("escimm (insfile )"),
sys.ADR("f2"), sys.ADR("escimm (newfile )"),
sys.ADR("f3"), sys.ADR("escimm (newwindow newfile)"),
sys.ADR("f6"), sys.ADR("saveold iconify"),
sys.ADR("f7"), sys.ADR("escimm (bsave )"),
sys.ADR("f8"), sys.ADR("saveold escimm (newfile )"),
sys.ADR("f9"), sys.ADR("saveold"),
sys.ADR("f10"), sys.ADR("saveold quit"),
sys.ADR("c-b"), sys.ADR("block"),
sys.ADR("c-u"), sys.ADR("unblock"),
sys.ADR("a-d"), sys.ADR("bdelete"),
sys.ADR("a-c"), sys.ADR("bcopy"),
sys.ADR("a-m"), sys.ADR("bmove"),
sys.ADR("a-s"), sys.ADR("bsource"),
sys.ADR("a-S"), sys.ADR("unblock block block bsource"),
sys.ADR("L-lmb"), sys.ADR("tomouse"), (* left button *)
sys.ADR("L-mmo"), sys.ADR("tomouse"), (* mouse move with left held down *)
sys.ADR("R-rmb"), sys.ADR("iconify"), (* right button *)
sys.ADR("a-("), sys.ADR("`:-)'")); (* Smily *)
VAR
HashList*: ARRAY Hashsize OF HashPtr;
cTOa: ARRAY NumRawKeyCodes OF CHAR;
csTOa: ARRAY NumRawKeyCodes OF CHAR;
SpecKey: POINTER TO SpecKeyCodeArray;
RetOvrString: edG.StringPtr; (* Zwischenspeicher für *)
RetOvrLen: INTEGER; (* PROC ReturnOveride *)
cqTOaBuffer: ARRAY 16 OF CHAR;
(* Ermittelt aus Raw-code und qualifiern einen String, der die Taste *)
(* in der Form `qual-Key' beschreibt (Umkehrfunktion von GetCodeQual) *)
PROCEDURE cqTOa*(code: BYTE; qual: SHORTSET): edG.StringPtr;
VAR
i,j: INTEGER;
BEGIN
i := 0;
IF qualShift IN qual THEN cqTOaBuffer[i] := "s"; INC(i); END;
IF qualCtrl IN qual THEN cqTOaBuffer[i] := "c"; INC(i); END;
IF qualAlt IN qual THEN cqTOaBuffer[i] := "a"; INC(i); END;
IF qualAmiga IN qual THEN cqTOaBuffer[i] := "A"; INC(i); END;
IF qualLmb IN qual THEN cqTOaBuffer[i] := "L"; INC(i); END;
IF qualMmb IN qual THEN cqTOaBuffer[i] := "M"; INC(i); END;
IF qualRmb IN qual THEN cqTOaBuffer[i] := "R"; INC(i); END;
cqTOaBuffer[i] := "-"; INC(i);
j := 0;
LOOP
IF SpecKey[j].code = code THEN (* Sondertaste? *)
cqTOaBuffer[i] := SpecKey[j].key[0];
cqTOaBuffer[i+1] := SpecKey[j].key[1];
cqTOaBuffer[i+2] := SpecKey[j].key[2];
INC(i,3);
EXIT;
END;
INC(j);
IF j = SpecKeyNum THEN (* Normale Taste *)
cqTOaBuffer[i] := cTOa[ORD(code)];
INC(i);
EXIT;
END;
END;
cqTOaBuffer[i] := 0X;
RETURN sys.ADR(cqTOaBuffer);
END cqTOa;
(* Ermittelt aus einem String, der die Taste in der Form `qual-Key' *)
(* beschreibt, Rawcode und qualifier (Umkehrfunktion von cqTOa) *)
PROCEDURE GetCodeQual(key: edG.StringPtr;
VAR code: BYTE; VAR qual: SHORTSET): BOOLEAN;
(* key : zu untersuchender String, z.B. "s-d"
code: Tastaturcode, qual: Qualifiers
*)
VAR
i, j, len: INTEGER;
help : ARRAY 3 OF CHAR;
BEGIN
i := 0;
qual := SHORTSET{};
len := str.Length(key^);
IF len > 1 THEN
WHILE (i < len) AND (key[i] # "-") DO
INC(i); END;
j := i;
WHILE j > 0 DO
DEC(j);
CASE key[j] OF
|"s" : INCL(qual,qualShift);
|"c" : INCL(qual,qualCtrl);
|"a" : INCL(qual,qualAlt);
|"A" : INCL(qual,qualAmiga);
|"L" : INCL(qual,qualLmb);
|"M" : INCL(qual,qualMmb);
|"R" : INCL(qual,qualRmb);
ELSE
qual := SHORTSET{};
j := i;
i := 0;
END;
END; (* WHILE *)
IF key[i] = "-" THEN INC(i); END;
END; (* len > 1 *)
IF len > i+1 THEN (* long name : more than this Byte left *)
help[0] := CAP(key[i]); (* nicht schoen, aber sicher *)
help[1] := CAP(key[i+1]); (* eine kurze Möglichkeit *)
help[2] := CAP(key[i+2]);
i := SpecKeyNum;
REPEAT (* entsprechenden Rawcode suchen *)
DEC(i);
IF help = SpecKey[i].key THEN
code := SpecKey[i].code;
RETURN TRUE;
END;
UNTIL i = 0;
ELSIF len = i+1 THEN (* single character keycap *)
j := 0; (* wichtig: von 0 aufwärts suchen, wg. NKx *)
REPEAT
IF key[i] = cTOa[j] THEN (* ohne Shift *)
code := SHORT(j);
RETURN TRUE;
END;
INC(j);
UNTIL j = NumRawKeyCodes;
j := 0;
REPEAT
IF key[i] = csTOa[j] THEN (* mit Shift *)
code := SHORT(j);
INCL(qual,qualShift);
RETURN TRUE;
END;
INC(j);
UNTIL j = NumRawKeyCodes;
END; (* IF len > i *)
RETURN FALSE;
END GetCodeQual;
(* Fügt einen String als Tastaturbelegung der mit code & qual angegebenen *)
(* Taste in die Tasaturbelegung (Hash!!) ein. Die Hash wird aus *)
(* (Rawcode AND 64) gebildet, und alle Tastaturbelegungen mit dieser Hash *)
(* an eine Kette gehängt. *)
PROCEDURE AddHash(code: BYTE; (*mask,*) qual:SHORTSET;
map: edG.StringPtr; sysMap: BOOLEAN);
VAR
thisHash: HashPtr;
hPtr: POINTER TO HashPtr;
HashValue: INTEGER;
BEGIN
HashValue := ORD(code) MOD Hashsize;
thisHash := HashList[HashValue];
hPtr := sys.ADR(HashList[HashValue]);
LOOP
IF thisHash = NIL THEN (* noch nicht belegt, einrichten *)
thisHash := e.AllocMem(sys.SIZE(Hash),LONGSET{e.memClear});
IF thisHash=NIL THEN
INCL (edG.Status,edG.memoryFail); edG.Rc := edE.cmdSevere;
RETURN;
END;
hPtr^ := thisHash;
thisHash.next := NIL;
thisHash.code := code;
(*thisHash.mask := mask;*)
thisHash.qual := qual;
EXIT;
END;
IF (thisHash.code = code) AND (* richtige Taste? *)
(*(thisHash.mask = mask) AND*)
(thisHash.qual = qual) THEN
(* Sysmap-Keys dürfen nicht DISPOSEd werden *)
IF thisHash.len # 0 THEN (* vom User belegt? *)
DISPOSE(thisHash.map); END; (* löschen *)
EXIT;
END;
hPtr := sys.ADR(thisHash.next);
thisHash := thisHash.next;
END; (* LOOP *)
IF NOT sysMap THEN
thisHash.map := edL.CopyString(map);
thisHash.len := str.Length(map^);
ELSE
thisHash.map := map; (* SysMap *)
thisHash.len := 0;
END;
END AddHash;
PROCEDURE RemHash(code: BYTE; (*mask,*) qual: SHORTSET);
VAR
thisHash, hnext,hlast: HashPtr;
HashValue: INTEGER;
BEGIN
HashValue := ORD(code) MOD Hashsize;
thisHash := HashList[HashValue];
WHILE thisHash # NIL DO
hnext := thisHash.next;
IF (thisHash.code = code) (*AND (thisHash.mask = mask)*)
AND (thisHash.qual = qual) THEN
IF thisHash.len # 0 THEN
DISPOSE(thisHash.map);
END;
IF thisHash = HashList[HashValue] THEN
HashList[HashValue] := thisHash.next;
ELSE
hlast.next := thisHash.next;
END;
e.FreeMem(thisHash,sys.SIZE(Hash));
RETURN;
END;
hlast := thisHash;
thisHash := hnext;
END;
END RemHash;
(* Löscht die komplette Tastatur Hash => Tastaturbelegung ist weg *)
PROCEDURE DeallocHash*;
VAR
thisHash, hnext: HashPtr;
i: SHORTINT;
BEGIN
i := Hashsize;
REPEAT
DEC(i);
thisHash := HashList[i];
WHILE thisHash # NIL DO
hnext := thisHash.next;
IF thisHash.len # 0 THEN DISPOSE(thisHash.map); END;
e.FreeMem(thisHash,sys.SIZE(Hash));
thisHash := hnext;
END;
HashList[i] := NIL;
UNTIL i = 0;
END DeallocHash;
(* Stellt die Default-Belegung für die Tasten her *)
PROCEDURE ResetHash*;
VAR
i: INTEGER;
code: BYTE;
qual: SHORTSET;
BEGIN
DeallocHash;
i := NumDefaultKeys;
REPEAT
DEC(i);
IF GetCodeQual(DefaultMap[i].from,code,qual) THEN
AddHash(code,(*sys.VAL(SHORTSET,0FFX),*)qual,DefaultMap[i].to,TRUE);
IF edG.memoryFail IN edG.Status THEN RETURN END;
END;
UNTIL i=0;
END ResetHash;
(* gibt die Adresse des String zurück, mit dem einem Key in der Form *)
(* `qual-Key' belegt ist *)
PROCEDURE KeySpectroMacro*(string: edG.StringPtr): edG.StringPtr;
VAR
thisHash: HashPtr;
code: BYTE;
qual: SHORTSET;
BEGIN
IF GetCodeQual(string,code,qual) THEN
thisHash := HashList[ORD(code) MOD Hashsize];
WHILE thisHash # NIL DO
IF (thisHash.code = code)
AND (thisHash.qual = (qual (** thisHash.mask*))) THEN
RETURN thisHash.map;
END;
thisHash := thisHash.next;
END; (* WHILE *)
END;
RETURN NIL;
END KeySpectroMacro;
(* belegt den Key in der Form `qual-Key' mit edG.Arg[1] *)
PROCEDURE doMap*;
VAR
code: CHAR;
qual: SHORTSET;
BEGIN
IF GetCodeQual(edG.Arg[0],code,qual) THEN (* code und qual suchen *)
AddHash(code,(*sys.VAL(SHORTSET,0FFX),*)qual,edG.Arg[1],FALSE);
ELSE
edG.Rc := edE.cmdError; edL.Title(UnknownKey);
END;
END doMap;
(* löscht die Belegung des Key's in der Form `qual-Key' *)
PROCEDURE doUnmap*;
VAR
code: CHAR;
qual: SHORTSET;
BEGIN
IF GetCodeQual(edG.Arg[0],code,qual) THEN (* code und qual suchen *)
RemHash(code,(*sys.VAL(SHORTSET,0FFX),*)qual); (* löschen *)
ELSE
edG.Rc := edE.cmdError; edL.Title(UnknownKey);
END;
END doUnmap;
(* ermittelt für Raw-Codes 0..127, um welche Taste es sich handelt *)
PROCEDURE KeyboardInit*;
VAR
i, len: INTEGER;
iEvent: ie.InputEventAdr;
buffer: ARRAY 32 OF CHAR;
qual: SHORTSET;
BEGIN
iEvent.nextEvent := NIL;
iEvent.class := ie.rawkey;
iEvent.subClass := 0;
i := NumRawKeyCodes;
REPEAT
DEC(i);
iEvent.code := i;
iEvent.qualifier := {};
iEvent.addr := NIL;
len := SHORT(con.RawKeyConvert(sys.ADR(iEvent),buffer,
sys.SIZE(buffer),NIL));
(* this first part is quiet dirty: changing consts (Bad!!). But it should *)
(* not matter, cause they are only depenting on the Keymaping. So every *)
(* call from a Process/Task using Std_Keymap gives the _same_ result. *)
CASE len OF
1: IF (buffer[0] >= CHR(32)) AND (buffer[0] < CHR(127)) THEN
cTOa[i] := buffer[0];
END;
CASE buffer[0] OF (* esc/del/tab/bs/nkx *)
1BX: SpecKey[ 0].code := CHR(i);
|7FX: SpecKey[11].code := CHR(i);
|09X: SpecKey[14].code := CHR(i);
|08X: SpecKey[12].code := CHR(i); SpecKey[13].code := CHR(i);
|"-": IF (i > 3AH) THEN SpecKey[22].code := CHR(i); END;
|".": IF (i > 3AH) THEN SpecKey[23].code := CHR(i); END;
|"(": IF (i > 3AH) THEN SpecKey[34].code := CHR(i); END;
|")": IF (i > 3AH) THEN SpecKey[35].code := CHR(i); END;
|"/": IF (i > 3AH) THEN SpecKey[36].code := CHR(i); END;
|"*": IF (i > 3AH) THEN SpecKey[37].code := CHR(i); END;
|"+": IF (i > 3AH) THEN SpecKey[38].code := CHR(i); END;
ELSE
IF (buffer[0] <= "9") AND (buffer[0] >= "0") AND (i >= 0FH) THEN
SpecKey[ORD(buffer[0])+(24-ORD("0"))].code := CHR(i); (* nkn *)
END;
END; (* CASE buffer[0] *)
|2: IF buffer[0] = ASCII.csi THEN (* cursor *)
CASE (buffer[1]) OF
"A": SpecKey[17].code := CHR(i); |
"B": SpecKey[18].code := CHR(i); |
"C": SpecKey[19].code := CHR(i); |
"D": SpecKey[20].code := CHR(i);
ELSE;
END;
END;
|3: IF (buffer[0] = ASCII.csi) AND (buffer[2] = 7EX) THEN (* funct/help *)
IF (buffer[1] >= "0") AND (buffer[1] <= "9") THEN
SpecKey[ORD(buffer[1])-(ORD("0")-1)].code := CHR(i);
ELSIF buffer[1] = "?" THEN
SpecKey[15].code := CHR(i);
END;
END;
ELSE;
END; (* CASE len *)
UNTIL i = 0;
i := NumRawKeyCodes;
REPEAT
DEC(i);
iEvent.code := i;
iEvent.qualifier := {ie.lShift};
iEvent.addr := NIL;
len := SHORT(con.RawKeyConvert(sys.ADR(iEvent),buffer,
sys.SIZE(buffer),NIL));
IF len = 1 THEN csTOa[i] := buffer[0]; END;
UNTIL i = 0;
IF GetCodeQual(sys.ADR("c"),edG.CtrlC,qual) THEN END;
END KeyboardInit;
(* überschreibt '-return' mit return bzw. (ggf. vorher gespeicherter) *)
(* alter belegung *)
PROCEDURE ReturnOveride*(overide: BOOLEAN);
VAR
thisHash: HashPtr;
BEGIN
thisHash := HashList[44H MOD Hashsize];
WHILE thisHash # NIL DO
IF (thisHash.code = ReturnRawCode) AND
(thisHash.qual = SHORTSET{}) THEN (* schon belegt *)
IF overide THEN
RetOvrString := thisHash.map;
RetOvrLen := thisHash.len;
thisHash.map := sys.ADR(Return);
thisHash.len := 0;
ELSE
IF RetOvrString = NIL THEN
RemHash(ReturnRawCode,(*sys.VAL(SHORTSET,0FFX),*)SHORTSET{});
ELSE
thisHash.map := RetOvrString;
thisHash.len := RetOvrLen;
END;
END;
RETURN;
END;
thisHash := thisHash.next;
END;
IF overide THEN (* noch nicht belgt *)
AddHash(ReturnRawCode,(*sys.VAL(SHORTSET,0FFX),*)SHORTSET{},
sys.ADR(Return),TRUE);
RetOvrString := NIL;
END;
END ReturnOveride;
PROCEDURE GetKeyText*(imsg: I.IntuiMessagePtr;
code: BYTE; qual: SET; VAR buffer: edG.String): INTEGER;
VAR
thisHash: HashPtr;
q2: SHORTSET;
blen,i: INTEGER;
bufPtr: edG.StringPtr;
BEGIN
blen := 0;
IF imsg # NIL THEN
IF NOT (edG.kick20 IN edG.Status) THEN
EXCL(imsg.qualifier,ie.repeat); END;
bufPtr := sys.ADR(buffer[1]);
blen := SHORT(sl.DeadKeyConvert(imsg,bufPtr^,edG.MaxLineLength-2,NIL));
IF blen <= 0 THEN RETURN -1; END;
END; (* imsg # NIL *)
q2 := SHORTSET{}; (* Qualifiers herausfinden *)
IF (qual * {ie.lCommand,ie.rCommand})#{} THEN INCL(q2,qualAmiga); END;
IF (qual * {ie.lShift,ie.rShift})#{} THEN INCL(q2,qualShift); END;
IF (qual * {ie.lAlt, ie.rAlt}) #{} THEN INCL(q2,qualAlt); END;
IF ie.control IN qual THEN INCL(q2,qualCtrl); END;
IF ie.leftButton IN qual THEN INCL(q2,qualLmb); END;
IF ie.midButton IN qual THEN INCL(q2,qualMmb); END;
IF ie.rightButton IN qual THEN INCL(q2,qualRmb); END;
IF (ie.capsLock IN qual) AND (blen = 1)
AND (buffer[1] >= "a") AND (buffer[1] <= "z") THEN
INCL(q2,qualShift); END;
code := CHR(ORD(code) MOD NumRawKeyCodes);
IF edG.numLock IN edG.Status THEN
i := 23; (* auf nk. *)
REPEAT
IF SpecKey[i].code = code THEN
buffer[0] := "'"; buffer[1] := SpecKey[i].key[2]; buffer[2] := 0X;
RETURN 1;
END;
INC(i);
UNTIL i > 33; (* hinter nk9 *)
END;
thisHash := HashList[ORD(code) MOD Hashsize];
LOOP
IF thisHash = NIL THEN EXIT; END; (* Taste belegt? *)
IF (thisHash.code = code)
AND (q2 (* * thisHash.mask*) = thisHash.qual) THEN
EXIT; END;
thisHash := thisHash.next;
END;
(* use HashList entry only if not in commandline or if the entry *)
(* does not correspont to an alpha key *)
IF thisHash # NIL THEN (* Taste belegt! *)
IF (q2 # SHORTSET{}) OR NOT (edG.commLineMode IN edG.Status)
OR (blen>1) OR (cTOa[ORD(code)] = 0X) THEN
blen := str.Length(thisHash.map^);
e.CopyMem(thisHash.map^,buffer,blen+1);
END;
ELSIF blen = 1 THEN (* einzelnes Zeichen *)
buffer[0] := "'";
buffer[2] := 0X;
ELSIF buffer[1] # ASCII.csi THEN (* keine Sondertaste *)
buffer[0] := "`";
buffer[blen+1] := "'";
buffer[blen+2] := 0X;
ELSE
buffer[0] := 0X;
END;
RETURN blen;
END GetKeyText;
(*-----------------------------------------------------------------------
* folgende beiden Prozeduren sind zum Debuggen. Es brauchen nur zwei
* Befehle eingebunden zu werden, die diese beiden Proc. ohne Parameter
* aufrufen.
* GetHash: zeigt alle Belegungen zu einem Raw-Key-Value
* GetMap: zeigt die Belegung einer Taste (Eingabe wie bei Map)
PROCEDURE doGetMap*;
BEGIN
edG.Arg[1] := KeySpectroMacro(edG.Arg[0]);
edL.Title(edG.Arg[1]^);
END doGetMap;
PROCEDURE doGetHash*;
VAR text: edG.StringPtr;
thisHash : HashPtr;
code : LONGINT;
BEGIN
IF edL.StrToInt(Key,code) THEN
thisHash := HashList[code MOD Hashsize];
WHILE thisHash # NIL DO
IF thisHash.code = sys.VAL(BYTE,SHORT(SHORT(code))) THEN
edL.Title(thisHash.map^); END;
thisHash := thisHash.next;
END; (* WHILE *)
END;
END doGetHash;
*)
BEGIN
(*RetOvrStr := NIL; RetOvrLen := 0;*)
SpecKey := sys.ADR(SpecKeyDef);
KeyboardInit; (* MainPort muß! bereits geöffnet sein *)
ResetHash;
IF edG.memoryFail IN edG.Status THEN HALT(20); END;
CLOSE
(*DISPOSE(RetOvrString); (* nicht erst über ReturnOveride(FALSE) *)*)
ReturnOveride(FALSE);
DeallocHash;
END EdKeyboard.